<?php
/**
 * User:
 * Date:
 * Time:
 */

namespace App\Common\RedisCache;


abstract class AbstractListCache extends AbstractCache
{
    /**
     * 是否json处理
     * @var bool
     */
    protected static $json = false;

    /**
     * 设置值
     * @param $value
     * @return mixed
     */
    public function set($value)
    {
        return $this->lPush($value);
    }

    /**
     * 获取值
     * @param string $key
     * @return mixed
     */
    public function get($key = '')
    {
        return $this->rPop($key);
    }

    /**
     * 获取值
     * @param string $key
     * @param int $timeout
     * @return mixed
     */
    public function brGet($key = '',$timeout = 0)
    {
        return $this->brPop($key,$timeout);
    }

    /**
     * @param string $key
     * @return int
     */
    public function len($key = ''): int
    {
        $this->select();

        if (empty($key)) {
            $key = $this->key;
        }

        return $this::$client->lLen($key);
    }

    public function lPush($value)
    {
        $this->select();

        if ($this::$json) {
            $value = json_encode($value);
        }
        return $this::$client->lPush($this->key, $value);
    }

    public function rPush($value)
    {
        $this->select();

        if ($this::$json) {
            $value = json_encode($value);
        }
        return $this::$client->rPush($this->key, $value);
    }

    public function lPop($key = '')
    {
        $this->select();

        if (empty($key)) {
            $key = $this->key;
        }
        $r = $this::$client->lPop($key);
        $this->raw_data = $r;
        if ($this::$json) {
            $r = json_decode($r, true);
        }
        return $r;
    }

    public function rPop($key = '')
    {
        $this->select();

        if (empty($key)) {
            $key = $this->key;
        }
        $r = $this::$client->rPop($key);
        $this->raw_data = $r;

        if ($this::$json) {
            $r = json_decode($r, true);
        }
        return $r;
    }

    public function bRpopLpush($dst_key, $timeout = 60, $key = '')
    {
        $this->select();

        if (empty($key)) {
            $key = $this->key;
        }
        $r = $this::$client->brpoplpush($key, $dst_key, $timeout);
        $this->raw_data = $r;

        if ($this::$json) {
            $r = json_decode($r, true);
        }
        return $r;
    }

    public function rpopLpush($dst_key, $key = '')
    {
        $this->select();

        if (empty($key)) {
            $key = $this->key;
        }
        $r = $this::$client->rpoplpush($key, $dst_key);
        $this->raw_data = $r;

        if ($this::$json) {
            $r = json_decode($r, true);
        }
        return $r;
    }

    public function lRange($start = 0, $end = -1, $key = '')
    {
        $this->select();

        if (empty($key)) {
            $key = $this->key;
        }
        $r = $this::$client->lRange($key, $start, $end);

        if ($this::$json) {
            foreach ($r as &$value) {
                $value = json_encode($value, true);
            }
        }

        return $r;
    }



    public function lRangeAll( $key = '')
    {
        $this->select();
        if (empty($key)) {
            $key = $this->key;
        }
        $r = $this::$client->lRange($key, 0, -1);
        return $r;
    }


    /**
     * 弹出列表中指定的一个元素
     * @param $key  列表key
     * @param $factor  元素
     */
    public function lrem($key,$factor){
        $this->select();
        if (empty($key)) {
            $key = $this->key;
        }
        $factor = (string) $factor;
        $this::$client->lRem($key,$factor,1);
    }



    /**
     * 获取列表左侧中第一个元素（不弹出）
     */
    public function lindex($key='', $position = 0) {
        $this->select();
        if (empty($key)) {
            $key = $this->key;
        }
        return $this::$client->lIndex($key, $position);
    }
    public function ltrim($key='', $start = 0, $end = 0) {
        $this->select();
        if (empty($key)) {
            $key = $this->key;
        }
        return $this::$client->lTrim($key, $start, $end);
    }
    public function brPop($key = '',$timeout = 0)
    {
        $this->select();

        if (empty($key)) {
            $key = $this->key;
        }
        $r = $this::$client->brPop($key,$timeout);

        if(empty($r)){
            return [];
        }

        $this->raw_data = $r[1];

        if ($this::$json) {
            $r = json_decode($r[1], true);
        }
        return $r;
    }
}
